package com.streetsmart;
/**
 * 
 * @author bhavani sudha
 *
 */
import java.util.List;
import java.util.concurrent.ExecutionException;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import com.streetsmart.DBManager;
import com.streetsmart.main.SSMainActivity;
/**
 * 
 * Issues three types of notifications. One is the routing periodic notification and the second is the notification for specific pending tasks
 * If the application is already in foreground no notification is issued. The third type of notification is when the entire plan needs to be rescheduled
 */
public class NotificationService extends IntentService {
	/*
	 * TODO need to do the following thigs 1. schedule for every 4 hours
	 * starting from 8 am in the morning till 8 pm in the night. 2. alsrm for
	 * each unscheduled MUST to DO event if the app is sleeping. 3. For 2. on
	 * creation and updation need to add alarm. While handling the alarm the 4.
	 * Notification service can check for the validity of the MUST to DO event.
	 * 5. programatically clear the notification that has already been processed
	 * by the user. 6. Add all the Alarm manager tasks to database 7. Add boot
	 * receiver class so that even after boot the alarams are retained. To
	 * retain retireve the database and reschedule all the alarams back. 8. NEED
	 * TO CHECK MUST TO DO EVENTS. CURRENTLY THE ALARM MANAGER TRIGGERS ALL MUST
	 * TO ALARMS IMMEIDATELY.
	 */
	static int Notification_ID = 0;
	static int Notification_Must_ID = 1;
	static int Notification_Reschedule_ID = 2;

	public NotificationService() {
		super("Notification Service");
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}

	@Override
	public void onHandleIntent(Intent arg0) {
		Log.i("StreetSmart-Log",
				"NotificationService invoked, starting ForeGround activity check in background");
		Log.i("StreetSmart-Log", "Intent: " + arg0.toString());
		boolean foreground = false;
		try {
			foreground = new ForegroundCheckTask().execute(getBaseContext())
					.get();
			// TODO need to know what is the application/activity name. In
			// future may be I need to write a separate service class.
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Bundle b = arg0.getExtras();
		if(b != null && b.containsKey("RESCHEDULE")){
			NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
			int icon = R.drawable.icon_contacts;
			CharSequence tickerText = "Reschedule?";
			long when = System.currentTimeMillis();
			Notification notification = new Notification(icon,
					tickerText, when);
			Context context = getApplicationContext();
			CharSequence contentTitle = "StreetSmart notification";
			CharSequence contentText = "You are running late. Press me to reschedule";
			Intent notificationIntent = new Intent(this,
					SSMainActivity.class);
			PendingIntent contentIntent = PendingIntent
					.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
			notification.setLatestEventInfo(context, contentTitle,
					contentText, contentIntent);
			notification.flags |= Notification.FLAG_AUTO_CANCEL;
			nm.cancelAll();
			Log.i("StreetSmart-Log",
					"Notification created for MUST, adding notification to the notification manager queue");
			nm.notify(Notification_Reschedule_ID, notification);
		}
		if (!foreground) {
			//b = arg0.getExtras();
			DBManager dbhelper;
			dbhelper = new DBManager(this);
			Cursor cur;
			if (b != null && b.containsKey("PERIODIC")) {
				cur = dbhelper.getAllUnscheduledGoodToDoEvents();
				int count = cur.getCount();
				dbhelper.close();
				if (count != 0 && Utilities.currentTimeIsNotNight()) {
					NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
					int icon = R.drawable.icon_contacts;
					CharSequence tickerText = "To do: " + count;
					long when = System.currentTimeMillis();
					Notification notification = new Notification(icon,
							tickerText, when);
					Context context = getApplicationContext();
					CharSequence contentTitle = "StreetSmart notification";
					CharSequence contentText = "You have " + count
							+ " unscheduled tasks";
					Intent notificationIntent = new Intent(this,
							SSMainActivity.class);
					PendingIntent contentIntent = PendingIntent.getActivity(
							this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
					notification.setLatestEventInfo(context, contentTitle,
							contentText, contentIntent);
					notification.flags |= Notification.FLAG_AUTO_CANCEL;
					nm.cancelAll();
					Log.i("StreetSmart-Log",
							"Notification created, adding notification to the notification manager queue");
					nm.notify(Notification_ID, notification);
				}
				cur.close();
			} else if(b != null){
				long id = b.getLong("ID");
				long time = b.getLong("TIME");
				Cursor cursor = dbhelper.getMustEventSchedule(id);
				if (cursor.getCount() > 0) {
					cursor.moveToFirst();
					if (b.containsKey("SPECIFIC")
							&& new Long(cursor.getLong(1)).compareTo(time) == 0){
							//& DBManager.mustEventsSchedule.containsKey(id)
							//&& (DBManager.mustEventsSchedule.get(id))
								//	.compareTo(time) == 0) {
						NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
						int icon = R.drawable.icon_contacts;
						CharSequence tickerText = "To do";
						long when = System.currentTimeMillis();
						Notification notification = new Notification(icon,
								tickerText, when);
						Context context = getApplicationContext();
						CharSequence contentTitle = "StreetSmart notification";
						CharSequence contentText = "You have 1 MUST TODO task in 1 hr";
						Intent notificationIntent = new Intent(this,
								SSMainActivity.class);
						PendingIntent contentIntent = PendingIntent
								.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
						notification.setLatestEventInfo(context, contentTitle,
								contentText, contentIntent);
						notification.flags |= Notification.FLAG_AUTO_CANCEL;
						nm.cancelAll();
						Log.i("StreetSmart-Log",
								"Notification created for MUST, adding notification to the notification manager queue");
						nm.notify(Notification_Must_ID, notification);
						dbhelper.deleteEventSchedule(id);
						//DBManager.mustEventsSchedule.remove(id);
					}
				}
				cursor.close();
			}
			dbhelper.close();
		}

	}

}
/**
 * 
 * check if the application is in foreground or not. 
 */
class ForegroundCheckTask extends AsyncTask<Context, Void, Boolean> {
	// used from
	// http://stackoverflow.com/questions/2314969/how-to-determine-if-one-of-my-activities-is-in-the-foreground
	@Override
	protected Boolean doInBackground(Context... params) {
		Log.i("StreetSmart-Log", "ActivityInForeGround check invoked");
		final Context context = params[0].getApplicationContext();
		return isAppOnForeground(context);
	}

	private boolean isAppOnForeground(Context context) {
		ActivityManager activityManager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> appProcesses = activityManager
				.getRunningAppProcesses();
		if (appProcesses == null) {
			return false;
		}
		final String packageName = context.getPackageName();
		for (RunningAppProcessInfo appProcess : appProcesses) {
			if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
					&& appProcess.processName.equals(packageName)) {
				return true;
			}
		}
		return false;
	}

}